package com.xie.smfs.entity;

import com.xie.smfs.registry.ModEffects;
import com.xie.smfs.registry.ModSounds;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.damage.DamageType;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.Identifier;
import net.minecraft.world.World;
import java.util.List;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import net.minecraft.block.Blocks;
import net.minecraft.block.DoorBlock;
import net.minecraft.block.enums.DoorHinge;
import net.minecraft.block.enums.DoubleBlockHalf;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import java.util.ArrayList;
import net.minecraft.server.world.ServerWorld;
import java.util.concurrent.atomic.AtomicInteger;

public class QiaomenGhostEntity extends GhostEntity {
    // 敲门鬼特有属性
    private static final boolean HAS_GHOST_DOMAIN = true;
    private static final int GHOST_DOMAIN_LEVEL = 4;
    private static final double GHOST_DOMAIN_RADIUS = 32.0;
    private static final char TERROR_LEVEL = 'A'; // A级恐怖
    private static final int KNOCK_DELAY = 10; // 每次敲门之间的延迟（tick）

    private int killCooldown;
    private int knockCooldown;
    private boolean isInitialPhase; // 标记是否为初始准备阶段
    private int knockSoundCounter; // 敲门声音计数器
    private int knockSoundDelay; // 敲门声音延迟
    //日志
    private static final Logger LOGGER = Logger.getLogger("QiaomenGhostEntity");

    public QiaomenGhostEntity(EntityType<QiaomenGhostEntity> entityType, World world) {
        super(entityType, world, HAS_GHOST_DOMAIN, GHOST_DOMAIN_LEVEL, GHOST_DOMAIN_RADIUS, TERROR_LEVEL);
        this.ghostLevel = 4; // 设置鬼等级
        this.isInitialPhase = true; // 初始为准备阶段
        this.killCooldown = 600; // 初始30秒准备时间（600刻）
        this.knockCooldown = 0;
        this.knockSoundCounter = 0;
        this.knockSoundDelay = 0;
    }

    @Override
    public void tick() {
        super.tick();

        // 处理敲门声音延迟播放
        if (knockSoundCounter > 0 && knockSoundDelay > 0) {
            knockSoundDelay--;
            if (knockSoundDelay <= 0) {
                this.playSound(SoundEvents.ENTITY_ZOMBIE_ATTACK_WOODEN_DOOR, 0.6F, 0.8F);
                knockSoundCounter--;
                if (knockSoundCounter > 0) {
                    knockSoundDelay = KNOCK_DELAY; // 设置下一次敲门的延迟
                }
            }
        }

        // 检查鬼域内是否还有玩家
        if (shouldDespawn()) {
            this.discard(); // 没有玩家时消失
            return;
        }

        // 初始准备阶段
        if (isInitialPhase) {
            if (killCooldown > 0) {
                killCooldown--;
            } else {
                isInitialPhase = false; // 结束初始准备阶段
                LOGGER.info("敲门鬼开始随机杀人 ");
                // 使用延迟播放3次敲门声
                playDelayedKnockSounds(0.6F, 0.8F, 3);
                executeKillPhase(); // 执行第一次杀人
                knockCooldown = 600; // 30秒后敲门
            }
            return;
        }

        // 正常循环阶段
        if (knockCooldown > 0) {
            knockCooldown--;
            if (knockCooldown <= 0) {
                executeKnockPhase(); // 执行敲门
                killCooldown = 600; // 30秒后杀人
            }
        } else if (killCooldown > 0) {
            killCooldown--;
            if (killCooldown <= 0) {
                executeKillPhase(); // 执行杀人
                knockCooldown = 600; // 30秒后敲门
            }
        }
    }

    @Override
    protected boolean shouldAttackPlayer(PlayerEntity player) {
        // 返回false，完全由tick方法控制攻击逻辑
        return false;
    }

    // 延迟播放敲门声音的方法
    private void playDelayedKnockSounds(float volume, float pitch, int knockCount) {
        if (this.getWorld().isClient) return;

        // 设置敲门计数器
        this.knockSoundCounter = knockCount;
        this.knockSoundDelay = 1; // 下一tick开始播放第一次敲门
    }

    // 检查鬼域内是否还有玩家
    private boolean shouldDespawn() {
        return this.getWorld().getPlayers().stream()
                .noneMatch(player -> this.squaredDistanceTo(player) <= GHOST_DOMAIN_RADIUS * GHOST_DOMAIN_RADIUS);
    }

    // 执行杀人阶段
    private void executeKillPhase() {
        List<PlayerEntity> targets = this.getWorld().getPlayers().stream()
                .filter(player -> this.squaredDistanceTo(player) <= GHOST_DOMAIN_RADIUS * GHOST_DOMAIN_RADIUS)
                .filter(player -> player.hasStatusEffect(ModEffects.GHOST_KNOCK))
                .collect(Collectors.toList());

        if (!targets.isEmpty()) {
            // 选择最近的玩家
            PlayerEntity target = targets.stream()
                    .min((p1, p2) -> Double.compare(this.squaredDistanceTo(p1), this.squaredDistanceTo(p2)))
                    .orElse(null);

            if (target != null) {
                executeAttack(target);
            }
        }
    }

    @Override
    protected void executeAttack(PlayerEntity player) {
        // 瞬移到玩家位置
        this.teleport(player.getX(), player.getY(), player.getZ());

        // 造成伤害
        RegistryEntry<DamageType> mobDamageType = this.getWorld().getRegistryManager().get(RegistryKeys.DAMAGE_TYPE)
                .getEntry(RegistryKey.of(RegistryKeys.DAMAGE_TYPE, new Identifier("smfs", "ghost")))
                .orElseThrow(() -> new IllegalStateException("MOB_ATTACK damage type not found"));
        DamageSource damageSource = new DamageSource(mobDamageType, this);
        player.damage(damageSource, Float.MAX_VALUE);

        // 施加虚弱效果
        player.addStatusEffect(new StatusEffectInstance(StatusEffects.WEAKNESS, 400, 1));

        // 在鬼自身位置生成门
        this.spawnDoorAt(this.getBlockPos());
    }

    // 执行敲门阶段
    private void executeKnockPhase() {
        searchDoorsAndSpreadBuff();
    }

    private void spawnDoorAt(BlockPos pos) {
        World world = this.getWorld();
        Direction facing = Direction.NORTH;

        // 直接替换方块生成下半部门
        world.setBlockState(pos, Blocks.OAK_DOOR.getDefaultState()
                .with(DoorBlock.FACING, facing)
                .with(DoorBlock.HINGE, DoorHinge.LEFT)
                .with(DoorBlock.OPEN, false)
                .with(DoorBlock.HALF, DoubleBlockHalf.LOWER));

        // 直接替换方块生成上半部门
        world.setBlockState(pos.up(), Blocks.OAK_DOOR.getDefaultState()
                .with(DoorBlock.FACING, facing)
                .with(DoorBlock.HINGE, DoorHinge.LEFT)
                .with(DoorBlock.OPEN, false)
                .with(DoorBlock.HALF, DoubleBlockHalf.UPPER));
    }

    private void searchDoorsAndSpreadBuff() {
        List<BlockPos> doorPositions = new ArrayList<>();
        BlockPos center = this.getBlockPos();
        int radius = (int) GHOST_DOMAIN_RADIUS;

        // 搜索鬼域范围内的所有门方块
        for (int x = -radius; x <= radius; x++) {
            for (int y = -radius; y <= radius; y++) {
                for (int z = -radius; z <= radius; z++) {
                    BlockPos pos = center.add(x, y, z);
                    if (this.getWorld().getBlockState(pos).getBlock() instanceof DoorBlock) {
                        doorPositions.add(pos);
                    }
                }
            }
        }

        // 如果没有找到门，在自身位置生成一个门
        if (doorPositions.isEmpty()) {
            BlockPos selfPos = this.getBlockPos();
            this.spawnDoorAt(selfPos);
            doorPositions.add(selfPos);
        }

        // 对每个门周围的玩家添加buff
        for (BlockPos doorPos : doorPositions) {
            // 传送到门的位置
            this.teleport(doorPos.getX() + 0.5, doorPos.getY(), doorPos.getZ() + 0.5);

            // 使用延迟播放3次敲门声
            playDelayedKnockSounds(0.6F, 0.8F, 3);

            //日志
            LOGGER.info("敲门鬼开始随机敲门 ");

            List<PlayerEntity> nearbyPlayers = this.getWorld().getPlayers().stream()
                    .filter(player -> player.squaredDistanceTo(doorPos.getX(), doorPos.getY(), doorPos.getZ()) <= 100.0)
                    .filter(player -> !player.hasStatusEffect(ModEffects.GHOST_KNOCK))
                    .collect(Collectors.toList());

            for (PlayerEntity player : nearbyPlayers) {
                player.addStatusEffect(new StatusEffectInstance(ModEffects.GHOST_KNOCK, 3600, 0), this);
                LOGGER.info("玩家被添加了鬼敲门效果。");
            }
        }
    }
}